using System;
using System.Collections.Generic;
using UnityEngine;


namespace ModuleUnitData
{
    /// <summary>
    /// UnitDL | MonoBehaviour 版本
    /// </summary>
    public class UnitDLMono : MonoSingletonBase<UnitDLMono>
    {
        /// <summary>
        /// 映射 | 数据层
        /// </summary>
        /// <remarks>
        /// 数据层 ：数据接口
        /// </remarks>
        public Dictionary<Type, IData> Libs { get; private set; } = new();

        /// <summary>
        /// 映射 | 关系表
        /// </summary>
        /// <remarks>
        /// 数据层 : 数据结构
        /// </remarks>
        public Dictionary<Type, Type> Maps { get; private set; } = new();



        #region 被动式管理数据

        /// <summary>s
        /// 获取 | 数据层
        /// </summary>
        public static ITData<T2> Get<T1, T2>()
            where T1 : UnityEngine.MonoBehaviour, IData // 数据层
            where T2 : class, new()              // 数据结构层

        {
            Type mapKey = typeof(T1);
            //Type libKey = typeof(T2);

            //bool isMap = Instance.Maps.TryGetValue(mapKey, out var outputType);
            //if (!isMap)
            //{
            //    Instance.Maps.TryAdd(mapKey, libKey);

            //    return Create<T1>() as ITData<T2>;
            //}

            bool isGet = Instance.Libs.TryGetValue(mapKey, out IData @IData);
            if (!isGet)
            {
                IData @new = Create<T1>();
                Instance.Libs.TryAdd(mapKey, @new);
                return @new as ITData<T2>;
            }

            return @IData as ITData<T2>;
        }

        /// <summary>
        /// 创建 | 数据层
        /// </summary>
        private static T Create<T>() where T : MonoBehaviour, IData
        {
            GameObject @newGamObejct = new($"{typeof(T).Name}");
            @newGamObejct.transform.SetParent(Instance.transform);

            T @new = @newGamObejct.AddComponent<T>();
            return @new;
        }

        #endregion

        #region 主动式管理数据

        /// <summary>
        /// 注册 | 数据结构
        /// </summary>
        public static void Register<T>(IData @IData)
        {
            bool isFind = Instance.Libs.TryGetValue(typeof(T), out IData _);
            if (isFind)
            {
                throw new Exception($"UnitDLMono | 数据层 | 重复的注册行为！{typeof(T).Name}");
            }

            Instance.Libs.TryAdd(typeof(T), @IData);
        }

        /// <summary>
        /// 注销 | 数据接口
        /// </summary>
        public static void UnRegister<T>() where T : IData
        {
            bool isFind = Instance.Libs.TryGetValue(typeof(T), out IData _);
            if (!isFind)
            {
                throw new Exception($"UnitDLMono | 数据层 | 无效的注销行为！{typeof(T).Name}");
            }

            Instance.Libs.Remove(typeof(T));
        }

        /// <summary>
        /// 获取 | 数据接口
        /// </summary>
        public static ITData<T2> Require<T1, T2>() 
            where T1 : IData             // 数据层
            where T2 : class, new()      // 数据结构层
        {
            bool isFind = Instance.Libs.TryGetValue(typeof(T1), out IData output);
            if (!isFind)
            {
                throw new Exception($"UnitDLMono | 数据层 | 无效的获取行为！{typeof(T1).Name}");
            }

            return output as ITData<T2>;
        }

        #endregion
    }
}